package codename.primavera.service.impl;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.springframework.dao.DataAccessException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import codename.primavera.model.User;
import codename.primavera.model.User_;
import codename.primavera.service.UserService;

/**
 * The Class UserServiceImpl.
 * @author AIEXM45
 */
@Repository
public class UserServiceImpl implements UserService {

    // @Resource
    /** The entity manager. */
    @PersistenceContext
    // GlassFish3: not allowed when using RESOURCE_LOCAL persistence unit
    private EntityManager entityManager;

    /** {@inheritDoc} */
    @SuppressWarnings("unchecked")
    @Override
    public List < User > search() {
        return entityManager.createQuery("from User").getResultList();
    }

    /** {@inheritDoc} */
    @Override
    public List < User > searchByCriteria() {
        CriteriaBuilder cb = entityManager.getCriteriaBuilder();
        CriteriaQuery < User > cq = cb.createQuery(User.class);
        cq.from(User.class);

        return entityManager.createQuery(cq).getResultList();
    }

    /** {@inheritDoc} */
    @Override
    public void delete(final User someUser) {
        entityManager.remove(someUser);

    }

    /** {@inheritDoc} */
    @Override
    @Transactional
    public void create(final User someUser) {
        entityManager.persist(someUser);
    }

    /** {@inheritDoc} */
    @Override
    @Transactional(readOnly=true)
    public UserDetails loadUserByUsername(final String username) throws UsernameNotFoundException,
            DataAccessException {
    	CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
    	CriteriaQuery<User> criteriaQuery = criteriaBuilder.createQuery(User.class);
    	Root<User> u = criteriaQuery.from(User.class);
    	Predicate usernameCondition = criteriaBuilder.equal(u.get(User_.username), username);
    	criteriaQuery.where(usernameCondition);
    	TypedQuery<User> query = entityManager.createQuery(criteriaQuery);
    	
    	
        try {
            return (User) query.getSingleResult();
        } catch (NoResultException e) {
            throw new UsernameNotFoundException("User not found: " + username, e);
        }
    }

    /** {@inheritDoc} */
    @Override
    public String getSuperSecretConfidentialPassword() {
       return "Admin says: 1337";
    }

}
